package com.ruicar.afs.cloud.basic.common.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.basic.common.entity.*;
import com.ruicar.afs.cloud.basic.common.mapper.BasicDebitInfoMapper;
import com.ruicar.afs.cloud.basic.common.service.BasicDebitInfoService;
import com.ruicar.afs.cloud.basic.common.service.BasicExpenseRecordService;
import com.ruicar.afs.cloud.basic.common.service.BasicMainInfoService;
import com.ruicar.afs.cloud.basic.common.service.BasicRepaymentPlanService;
import com.ruicar.afs.cloud.common.modules.contract.enums.*;
import com.ruicar.afs.cloud.common.util.EmptyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author: Lee
 * @date 2020-05-30 04:35:07
 * @description
 */
@Service
public class BasicDebitInfoServiceImpl extends ServiceImpl<BasicDebitInfoMapper, BasicDebitInfo> implements BasicDebitInfoService {
    @Autowired
    private BasicRepaymentPlanService basicRepaymentPlanService;
    @Autowired
    private BasicExpenseRecordService basicExpenseRecordService;
    @Autowired
    private BasicMainInfoService basicMainInfoService;

    @Override
    public BigDecimal getCurrentArrears(String contractNo, Date batchDate) {
        BigDecimal arrears = BigDecimal.ZERO;
        /**  租金 by ZC.GUO  **/
        List<RepaymentStatusEnum> repaymentStatusEnumList = new ArrayList<RepaymentStatusEnum>();
        repaymentStatusEnumList.add(RepaymentStatusEnum.UNPAID);
        repaymentStatusEnumList.add(RepaymentStatusEnum.OVERDUE);
        List<BasicRepaymentPlan> repaymentPlanList = basicRepaymentPlanService.list(Wrappers.<BasicRepaymentPlan>query().lambda()
                .eq(BasicRepaymentPlan::getContractNo, contractNo)
                .in(BasicRepaymentPlan::getStatus, repaymentStatusEnumList)
                .le(BasicRepaymentPlan::getDueDate, DateUtil.endOfDay(batchDate))
        );
        if (EmptyUtils.isNotEmpty(repaymentPlanList)) {
            for (BasicRepaymentPlan plan : repaymentPlanList) {
                arrears = arrears.add(plan.getReceivableRent().subtract(EmptyUtils.isNotEmpty(plan.getActualRent()) ? plan.getActualRent() : BigDecimal.ZERO));
            }
        }
        /**  费用（包括罚息） by ZC.GUO  **/
        List<BasicExpenseRecord> basicExpenseRecordList = basicExpenseRecordService.list(Wrappers.<BasicExpenseRecord>query().lambda()
                .eq(BasicExpenseRecord::getStatus, ExpenseStatusEnum.unsettle)
                .eq(BasicExpenseRecord::getContractNo, contractNo)
                .gt(BasicExpenseRecord::getRemainingAmt, BigDecimal.ZERO)
        );
        if (EmptyUtils.isNotEmpty(basicExpenseRecordList)) {
            for (BasicExpenseRecord record : basicExpenseRecordList) {
                arrears = arrears.add(record.getRemainingAmt());
            }
        }
        return arrears;
    }

    @Override
    public void reCalculateAfterReceipt(BasicReceiptRecord receiptRecord) {
        BasicMainInfo basicMainInfo = basicMainInfoService.getOne(Wrappers.<BasicMainInfo>query().lambda().eq(BasicMainInfo::getContractNo, receiptRecord.getContractNo()), false);
        BasicDebitInfo debitInfo = this.getOne(Wrappers.<BasicDebitInfo>query().lambda().eq(BasicDebitInfo::getContractNo,receiptRecord.getContractNo()));
        /**  租金 by ZC.GUO  **/
        List<RepaymentStatusEnum> repaymentStatusEnumList = new ArrayList<RepaymentStatusEnum>();
        repaymentStatusEnumList.add(RepaymentStatusEnum.UNPAID);
        repaymentStatusEnumList.add(RepaymentStatusEnum.OVERDUE);
        List<BasicRepaymentPlan> repaymentPlanList = basicRepaymentPlanService.list(Wrappers.<BasicRepaymentPlan>query().lambda()
                .eq(BasicRepaymentPlan::getContractNo, receiptRecord.getContractNo())
                .in(BasicRepaymentPlan::getStatus, repaymentStatusEnumList)
        );

        /**  剩余本金 by ZC.GUO  **/
        BigDecimal remainPrincipal = BigDecimal.ZERO;
        /**  剩余租金 by ZC.GUO  **/
        BigDecimal remainRent = BigDecimal.ZERO;
        /**  逾期总额 by ZC.GUO  **/
        BigDecimal totalOverdueAmt = BigDecimal.ZERO;
        if (EmptyUtils.isNotEmpty(repaymentPlanList)) {
            /**  是否逾期 by ZC.GUO  **/
            boolean isOverdue = false;
            for (BasicRepaymentPlan plan : repaymentPlanList) {
                /**  剩余租金 by ZC.GUO  **/
                remainRent = remainRent.add(plan.getReceivableRent().subtract(EmptyUtils.isNotEmpty(plan.getActualRent()) ? plan.getActualRent() : BigDecimal.ZERO));
                /**  剩余本金 by ZC.GUO  **/
                remainPrincipal = remainPrincipal.add(plan.getReceivablePrinciple().subtract(EmptyUtils.isNotEmpty(plan.getActualPrinciple()) ? plan.getActualPrinciple() : BigDecimal.ZERO));
                if (RepaymentStatusEnum.OVERDUE.equals(plan.getStatus())){
                    /**  标记逾期 by ZC.GUO  **/
                    isOverdue = true;
                    /**  计算逾期总额 by ZC.GUO  **/
                    totalOverdueAmt = totalOverdueAmt.add(plan.getReceivableRent().subtract(EmptyUtils.isNotEmpty(plan.getActualRent())?plan.getActualRent():BigDecimal.ZERO));
                }
            }
            if (isOverdue){
                /**  设置借据逾期 by ZC.GUO  **/
                debitInfo.setIsOverdue(YesOrNoEnum.yes);
                /**  设置合同状态逾期 by ZC.GUO  **/
                basicMainInfo.setContractStatus(ContractStatusEnum.overdue);
            }else{
                /**  设置借据不逾期,逾期天数清零 by ZC.GUO  **/
                debitInfo.setIsOverdue(YesOrNoEnum.no);
                debitInfo.setCurrentAbsoluteOverdue(0);
                debitInfo.setCurrentRelativeOverdue(0);
                /**  设置合同状态正常 by ZC.GUO  **/
                basicMainInfo.setContractStatus(ContractStatusEnum.contractEffective);
            }
        }else{
            /**  所有还款计划完成还款，设置正常结清或提前结清 by ZC.GUO  **/
            if (WriteTargetTypeEnum.beforeCharge.equals(receiptRecord.getWriteTarget())) {
                basicMainInfo.setContractStatus(ContractStatusEnum.advanceSettle);
            } else {
                basicMainInfo.setContractStatus(ContractStatusEnum.normalSettle);
            }
            /**  设置借据不逾期,逾期天数清零 by ZC.GUO  **/
            debitInfo.setIsOverdue(YesOrNoEnum.no);
            debitInfo.setCurrentAbsoluteOverdue(0);
            debitInfo.setCurrentRelativeOverdue(0);
        }
        debitInfo.setRemainPrinciple(remainPrincipal);
        debitInfo.setTotalResidualRent(remainRent);
        debitInfo.setOverdueTotalAmount(totalOverdueAmt);
        this.updateById(debitInfo);
        basicMainInfoService.updateById(basicMainInfo);
    }
}
